package com.qing.springcloud.advice;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONUtil;
import com.qing.springcloud.annotation.SkipResponseWrapper;
import com.qing.springcloud.exception.ExceptionTypeEnum;
import com.qing.springcloud.common.Result;
import com.qing.springcloud.exception.BusinessException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Method;

/**
 * @author caozhipeng
 * @date 2025/7/18
 */
@Slf4j
@RestControllerAdvice
public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        Method method = returnType.getMethod();
        // 检查是否有 SkipResponseWrapper 注解，有则不进行封装
        if (ObjUtil.isNotNull(method) && (method.isAnnotationPresent(SkipResponseWrapper.class) ||
                method.getDeclaringClass().isAnnotationPresent(SkipResponseWrapper.class))) {
            return body;
        }
        if (shouldSkip(body)) {
            return body;
        }else{
            try {
                // 封装统一返回值
                return Result.success(body);
            } catch (BusinessException e) {
                return Result.fail(e);
            }catch (RuntimeException e){
                // 异常处理，返回失败结果
                return Result.fail(e);
            }catch (Exception e) {
                // 异常处理，返回失败结果
                return Result.fail(e);
            }
        }

//        if (ObjUtil.isNotNull(method)&&(method.isAnnotationPresent(ResponseResult.class) ||
//                method.getDeclaringClass().isAnnotationPresent(ResponseResult.class))) {
//            if (shouldSkip(body)) {
//                return body;
//            } else {
//                try {
////                    处理String转换异常或者配置全局的序列化
//                   *//* if (selectedConverterType == StringHttpMessageConverter.class) {
//                        ObjectMapper mapper = new ObjectMapper();
//                        return mapper.writeValueAsString(Result.success(body)); // 手动转换为 JSON 字符串
//                    }*//*
//                    // 封装统一返回值
//                    return Result.success(body);
//                }catch (RuntimeException e){
//                    // 异常处理，返回失败结果
//                    return Result.fail(e);
//                }catch (Exception e) {
//                    // 异常处理，返回失败结果
//                    return Result.fail(e);
//                }
//            }
//        }
    }

    private boolean shouldSkip(Object result) {
        return  result instanceof Result ||
                result instanceof ResponseEntity ||
                result instanceof ModelAndView;
    }

    @ExceptionHandler(value = Exception.class) // 捕获 Controller 中抛出的指定类型的异常，也可以指定其他异常
    public Object handler(Exception exception, HttpServletRequest request) {
        if(exception instanceof BusinessException){
            log.warn("【自定义异常信息】{}", JSONUtil.toJsonStr(exception.getMessage()));
        }else{
            exception.printStackTrace();
            return Result.fail(ExceptionTypeEnum.SYSTEM_ERROR);
        }
        return Result.fail(exception);
    }


}